package ace.module.account.core.impl.service.authentication.handler.impl;

import ace.cmp.core.exception.BusinessException;
import ace.cmp.json.api.JsonService;
import ace.module.account.api.model.auth.dto.AuthenticationResult;
import ace.module.account.api.model.auth.input.AuthenticationParams;
import ace.module.account.api.model.auth.input.GenericAuthenticationInput;
import ace.module.account.api.model.auth.input.GenericAuthenticationInputImpl;
import ace.module.account.core.impl.service.authentication.handler.AuthenticationHandler;
import ace.module.account.core.impl.service.authentication.handler.model.input.AuthenticationHandlerContextInput;
import java.lang.reflect.Type;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.ResolvableType;

/**
 * @author caspar
 * @date 2023/3/16 9:49
 */
@Slf4j
public abstract class AbstractAuthenticationHandler<
        TParams extends AuthenticationParams,
        TInput extends GenericAuthenticationInputImpl<TParams>>
    implements AuthenticationHandler<TParams> {

  private final Type inputType;
  private final String grantType;
  private final JsonService jsonService;

  protected AbstractAuthenticationHandler(String grantType, JsonService jsonService) {
    this.inputType = ResolvableType.forType(this.getClass()).getSuperType().getGeneric(1).getType();
    this.grantType = grantType;
    this.jsonService = jsonService;
  }

  @Override
  public AuthenticationResult authentication(
      AuthenticationHandlerContextInput<TParams> contextInput) {
    return this.doAuthentication(contextInput);
  }

  protected abstract AuthenticationResult doAuthentication(
      AuthenticationHandlerContextInput<TParams> context);

  @Override
  public TParams convert(String input) {
    try {
      return ((GenericAuthenticationInput<TParams>)
              this.jsonService.toObject(input, this.inputType))
          .getBizParams();
    } catch (Exception ex) {
      log.error("AbstractAuthenticationHandler_convert_error", ex);
      throw new BusinessException("转换认证业务参数失败");
    }
  }

  @Override
  public String getGrantType() {
    return this.grantType;
  }
}
